﻿using System.IO.Ports;

#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.

namespace NewDevice.RS485
{
    /// <summary>
    /// 8通道电阻测量模块
    /// </summary>
    public class ZhT08R14N1_V2
    {
        #region 初始化设置指令

        //01 06 00 51 00 00 //设置波特率115200
        //01 06 01 FB 00 10 //主动上传使能
        //01 06 01 FC 06 00 //RS485 接口主动上传类型选择
        //阻值=读值/100

        #endregion 初始化设置指令

        private readonly Dictionary<int, List<short>> _registerValues = new Dictionary<int, List<short>>();
        private readonly SerialPort _serialPort; // 串口对象
                                                 // 缓存寄存器历史值

        private bool _isNote = false;
        private bool _isReading = true;
        private List<byte> _noteData;
        private ManualResetEvent _stopNote;

        /// <summary>
        /// 构造函数，允许传入串口名称和波特率
        /// </summary>
        /// <param name="portName"></param>
        /// <param name="baudRate"></param>
        public ZhT08R14N1_V2(string portName = "COM7", int baudRate = 115200)
        {
            _serialPort = new SerialPort(portName, baudRate);
        }

        /// <summary>
        /// 属性：外部可访问的寄存器历史值
        /// </summary>
        public Dictionary<int, List<double>> RegisterValues
        {
            get
            {
                // 返回 _registerValues 的深拷贝，并对所有值处理后，保留三位小数
                return _registerValues.ToDictionary(
                    kvp => kvp.Key, // 键是 int，直接复制
                    kvp => kvp.Value.Select(v => Math.Round(v / 100.0, 3)).ToList() // 对 List<Int16> 中的每个值除以 1000，并保留三位小数
                );
            }
        }

        /// <summary>
        /// 断开TCP连接并停止所有任务
        /// </summary>
        public void Disconnect()
        {
            _isReading = false;
            _serialPort?.Close();
        }

        public void Open()
        {
            _serialPort.Open();
            Task.Run(() =>
            {
                while (_isReading)
                {
                    ReadBuffer();
                }
            });
        }

        public void StartNote()
        {
            if (_isNote)
            {
                _isNote = false;
                _stopNote = new ManualResetEvent(false);
                if (!_stopNote.WaitOne(100))
                {
                    throw new Exception($"{nameof(ZhT08R14N1_V2)} {nameof(StartNote)} wait stop timeout");
                }
            }
            _registerValues.Clear();
            _noteData = new List<byte>();
            _isNote = true;
        }

        public void StopNote()
        {
            _isNote = false;
            ParseData();
        }

        private void ParseData()
        {
            int offset = 0;
            while (offset + 21 <= _noteData.Count)
            {
                if (_noteData[offset] == 0x01 && _noteData[offset + 1] == 0x03 && _noteData[offset + 2] == 0x10)
                {
                    byte[] dataPacket = new byte[21];
                    Buffer.BlockCopy(_noteData.ToArray(), offset, dataPacket, 0, 21);

                    ParseReceivedData(dataPacket);

                    offset += 21;
                }
                else
                {
                    offset++;
                }
            }
        }

        /// <summary>
        /// 解析接收到的数据包
        /// </summary>
        /// <param name="data">接收到的数据</param>
        private void ParseReceivedData(byte[] data)
        {
            if (data.Length < 5) return;

            byte address = data[0];
            byte opCode = data[1];
            byte dataLength = data[2];

            if (data.Length < 3 + dataLength + 2) return;

            byte[] registerData = new byte[dataLength];
            Array.Copy(data, 3, registerData, 0, dataLength);

            ParseRegisterValues(registerData);
        }

        // 解析寄存器值并更新缓存
        private void ParseRegisterValues(byte[] data)
        {
            // 每 2 个字节代表一个寄存器的值
            for (int i = 0; i < data.Length; i += 2)
            {
                if (i + 1 >= data.Length) // 确保有足够的数据
                {
                    break;
                }

                // 寄存器地址（假设从 0 开始递增）
                int registerAddress = i / 2;

                // 寄存器值（16 位，大端序）
                Int16 registerValue = (Int16)((data[i] << 8) | data[i + 1]);

                // 初始化寄存器的历史值列表（如果不存在）
                if (!_registerValues.ContainsKey(registerAddress))
                {
                    _registerValues[registerAddress] = new List<Int16>();
                }

                // 如果历史值列表超过 1000 条，移除最早的数据
                var registerHistory = _registerValues[registerAddress];
                registerHistory!.Add(registerValue);
            }
        }

        private void ReadBuffer()
        {
            byte[] buffer = new byte[_serialPort.BytesToRead];
            var count = _serialPort.Read(buffer, 0, buffer.Count());
            if (_isNote)
            {
                if (count > 0)
                {
                    _noteData.AddRange(buffer);
                }
            }
            else
            {
                _stopNote?.Set();
            }
            Thread.Sleep(10);
        }
    }
}